package com
{
	import Box2D.Collision.Shapes.b2Shape;
	import Box2D.Collision.b2AABB;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.Joints.b2MouseJoint;
	import Box2D.Dynamics.Joints.b2MouseJointDef;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2Fixture;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;

	public class DragDemo extends Demo
	{
		public var m_mouseJoint:b2MouseJoint;
		
		
		static public var mouse:Sprite;
		static public var mouseDown:Boolean = false;
		static public var mouseReleased:Boolean = false;
		static public var mousePressed:Boolean = false;
		static public var mouseOver:Boolean = false;
		static public var mouseOffsetX:Number = 0;
		static public var mouseOffsetY:Number = 0;
		static public var mouseDragX:Number = 0;
		static public var mouseDragY:Number = 0;
		public function DragDemo(s:Sprite)
		{
			super(s);
			mouse = new Sprite();
			mouse.graphics.lineStyle(0.1, 0, 100);
			mouse.graphics.moveTo(0,0);
			mouse.graphics.lineTo(0,0.1);
			
			// mouse listeners
			s.stage.addEventListener(MouseEvent.MOUSE_DOWN, mousePress, false, 0, true);
			s.stage.addEventListener(MouseEvent.CLICK, mouseRelease, false, 0, true);
			s.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove, false, 0, true);
			s.stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave, false, 0, true);
		}
		
		override protected function run(e:Event):void{
			super.run(e);
			UpdateMouseWorld();
			MouseDrag();
		}//======================
		// Update mouseWorld
		//======================
		public function UpdateMouseWorld():void{
			mouseXWorldPhys = (_mouseX)/m_physScale; 
			mouseYWorldPhys = (_mouseY)/m_physScale; 
			
			mouseXWorld = (_mouseX); 
			mouseYWorld = (_mouseY); 
		}
		//======================
		// Mouse Drag 
		//======================
		public function MouseDrag():void{
			// mouse press
			if (mouseDown && !m_mouseJoint){
				
				var body:b2Body = GetBodyAtMouse();
				
				if (body)
				{
					var md:b2MouseJointDef = new b2MouseJointDef();
					md.bodyA = m_world.GetGroundBody();
					md.bodyB = body;
					md.target.Set(mouseXWorldPhys, mouseYWorldPhys);
					md.collideConnected = true;
					md.maxForce = 300.0 * body.GetMass();
					m_mouseJoint = m_world.CreateJoint(md) as b2MouseJoint;
					body.SetAwake(true);
				}
			}
			
			
			// mouse release
			if (!mouseDown){
				if (m_mouseJoint)
				{
					m_world.DestroyJoint(m_mouseJoint);
					m_mouseJoint = null;
				}
			}
			
			
			// mouse move
			if (m_mouseJoint)
			{
				var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
				m_mouseJoint.SetTarget(p2);
			}
		}
		
		//======================
		// mousePress listener
		//======================
		public function mousePress(e:MouseEvent):void{
			mousePressed = true;
			mouseDown = true;
			mouseDragX = 0;
			mouseDragY = 0;
		}
		
		
		
		//======================
		// mousePress listener
		//======================
		public function mouseRelease(e:MouseEvent):void{
			mouseDown = false;
			mouseReleased = true;
		}
		
		
		
		//======================
		// mousePress listener
		//======================
		public function mouseLeave(e:Event):void{
			mouseReleased = mouseDown;
			mouseDown = false;
		}
		
		
		
		//======================
		// mouseMove listener
		//======================
		public function mouseMove(e:MouseEvent):void{
			
			// Fix mouse release not being registered from mouse going off stage
			if (mouseDown != e.buttonDown){
				mouseDown = e.buttonDown;
				mouseReleased = !e.buttonDown;
				mousePressed = e.buttonDown;
				mouseDragX = 0;
				mouseDragY = 0;
			}
			
			_mouseX = e.stageX - s.x;
			_mouseY = e.stageY - s.y;
			// Store offset
			mouseOffsetX = _mouseX - s.x;
			mouseOffsetY = _mouseY - s.y;
			// Update drag
			if (mouseDown){
				mouseDragX += mouseOffsetX;
				mouseDragY += mouseOffsetY;
			}
			mouse.x = _mouseX;
			mouse.y = _mouseY;
		}
		
		//======================
		// GetBodyAtMouse
		//======================
	}
}